package com.clx.rmp.common.classloader;

import com.clx.rmp.common.constant.DirConstant;
import com.clx.rmp.common.utils.EncryptUtil;
import com.clx.rmp.common.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;


/**
 * classpath 路径里面的类无法被加载的----需要修改底层的类加载器
 * <p>
 * 应用场景---热部署
 */
@Slf4j
public class MyClassLoader extends ClassLoader {

    private String path;

    public MyClassLoader(String path) {
        this.path = path;
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        System.out.println("正在加载name=" + name);
        Class<?> aClass = null;
        try {
            aClass = MyClassLoader.class.getClassLoader().loadClass(name);//先使用应用类加载器去加载
        } catch (Exception e) {
            //由父类先加载,找不到就会报异常
        }

        if (aClass != null) {
            return aClass;
        }
        return findClass(name);
    }

    /**
     * 重写父类的findClass方法，在ClassLoader在执行 loadClass 方法时，
     * 如果父加载器不会加载类，就会调用当前重写的方法进行加载类
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        System.out.println("查找类name=" + name);
        //自定义的
        if (name.startsWith(DirConstant.ENCRYPT_PACKAGE_NAME)) {
            //自定义的
            String filePath = DirConstant.CONF_HOME_DIR + File.separator + name.replaceAll("\\.", File.separator + File.separator) + ".class";
            byte[] bytes = FileUtil.readByte(filePath);
            byte[] decrypt = EncryptUtil.decrypt(bytes);
            int len = decrypt.length;
            return defineClass(null, decrypt, 0, len);
        } else {
            return super.findClass(name);
        }
    }
}


